package com.sl.diary.activity;

import java.util.ArrayList;
import java.util.List;

import com.sl.diary.R;
import com.sl.diary.adapter.TravelItemAdapter;
import com.sl.diary.adapter.TravelItemAdapter.TravelItemAdapterEventCallback;
import com.sl.diary.callback.AlertDialogCallBack;
import com.sl.diary.component.ListPopup;
import com.sl.diary.component.ListPopup.PopupItemAdapterEventCallback;
import com.sl.diary.component.LoadMoreListView;
import com.sl.diary.component.LoadMoreListView.OnLoadMoreListener;
import com.sl.diary.db.TravelSQLiteHelper;
import com.sl.diary.model.TravelModel;
import com.sl.diary.util.Constant;

import android.content.Context;
import android.content.Intent;
import android.os.AsyncTask;
import android.os.Bundle;
import android.view.Display;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.ImageView;

public class A003_TravelList extends BaseActivity implements
		TravelItemAdapterEventCallback, PopupItemAdapterEventCallback,
		AlertDialogCallBack {

	List<TravelModel> travels;
	LoadMoreListView lv_travels;
	TravelItemAdapter adapter_travels;
	int current_travel_offset = 0, amount_travel = 8;

	/** selected travel */
	TravelModel selected_travel = null;

	/** the sort type of travel list */
	ListPopup list_popup;
	int SORT_DEFAULT = 0;
	int SORT_NAME = 1;
	int SORT_DATE = 2;
	int SORT_TYPE = SORT_DEFAULT;

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.a003_travel_list);
		this.initView();
	}

	@Override
	public boolean onCreateOptionsMenu(Menu menu) {
		// Inflate the menu; this adds items to the action bar if it is present.
		return true;
	}

	@Override
	protected void onResume() {
		// TODO Auto-generated method stub
		super.onResume();
		// return from tapping back button 
		if (selected_travel != null) {
			boolean isExistedTravel = dbManager.isExistedTravel(selected_travel.getId());
			if(isExistedTravel){
				updateList(Constant.TRAVEL_STATE_EDIT, Constant.A003_CODE);
			}else{
				updateList(Constant.TRAVEL_STATE_DEL, Constant.A003_CODE);
			}
		}
	}

	@Override
	protected void onActivityResult(int requestCode, int resultCode, Intent data) {
		super.onActivityResult(requestCode, resultCode, data);
		if (data == null) {
			// return from tapping back button
		} else {
			Bundle bundle = data.getExtras();
			updateList(bundle.getInt(Constant.TRAVEL_STATE), resultCode);
		}
	}

	private void initView() {
		super.initNavigationBar();
		// buttons in navigation bar
		ImageView imgbtn_sort = (ImageView) findViewById(R.id.imgbtn_navigation_sort);
		imgbtn_sort.setOnClickListener(onClickSortTravels);

		// get all travels from database
		if (dbManager != null) {

			if (amount_travel == 0) {
				LayoutInflater inflater = (LayoutInflater) getApplicationContext()
						.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
				View view = inflater.inflate(R.layout.a003_travel_list_row,
						null);

				Display display = getWindowManager().getDefaultDisplay();
				amount_travel = Math.round((display.getHeight() - navigation_bar
						.getHeight()) / view.getHeight());
			}

			travels = getTraveListForSortType(SORT_TYPE, amount_travel,
					current_travel_offset);
			current_travel_offset += amount_travel;

			lv_travels = (LoadMoreListView) findViewById(R.id.lv_travels);
			adapter_travels = new TravelItemAdapter(
					this.getApplicationContext(), R.id.lv_travels, travels);
			adapter_travels.setCallback(this);
			lv_travels.setAdapter(adapter_travels);
			lv_travels.setOnLoadMoreListener(onLoadMoreTraves);
		}
	}

	/**
	 * 
	 * @param travelState
	 *            -
	 * @param activityCode
	 */
	private void updateList(int travelState, int activityCode) {
		if (travelState == Constant.TRAVEL_STATE_EDIT) {
			travels.set(travels.indexOf(selected_travel),
					dbManager.getTravel(selected_travel.getId()));
			adapter_travels.notifyDataSetChanged();
			// navigate to A004_TravelDetail
			if (activityCode == Constant.A005_CODE) {
				Intent intent = new Intent(A003_TravelList.this,
						A004_TravelDetail.class);
				intent.putExtra(TravelSQLiteHelper.TRAVEL_ID,
						selected_travel.getId());
				startActivityForResult(intent, Constant.A003_CODE);
			}
		} else if (travelState == Constant.TRAVEL_STATE_DEL) {
			travels.remove(selected_travel);
			adapter_travels.notifyDataSetChanged();
			current_travel_offset -= 1;
		}
		// set default for selected_travel
		selected_travel = null;
	}

	/**
	 * get travels for sort type
	 * 
	 * @param sort_type
	 *            the int
	 */
	private List<TravelModel> getTraveListForSortType(int sort_type,
			int amount, int offset) {

		List<TravelModel> travels = new ArrayList<TravelModel>();

		if (sort_type == SORT_NAME) {
			travels = dbManager.getAllTravelBySortName(amount_travel,
					current_travel_offset);
		} else if (sort_type == SORT_DATE) {
			travels = dbManager.getAllTravelBySortDate(amount_travel,
					current_travel_offset);
		} else {
			travels = dbManager.getAllTravel(amount_travel, current_travel_offset);
		}
		return travels;
	}

	OnLoadMoreListener onLoadMoreTraves = new OnLoadMoreListener() {

		@Override
		public void onLoadMore() {
			// Do the work to load more items at the end of list here
			new LoadDataTask().execute();

		}
	};

	/**
	 * OnClickListener - handle click event on sort btn on navigationbar show
	 * dialog with 2 options: sort by name and sort by date
	 */
	OnClickListener onClickSortTravels = new OnClickListener() {

		@Override
		public void onClick(View view) {
			/** The show map type array. */
			String[] sortTypeArray = { "Sor by Name", "Sort by Date" };
			if (list_popup == null) {
				list_popup = new ListPopup(A003_TravelList.this);
				list_popup.setData(sortTypeArray, A003_TravelList.this);
			}
			list_popup.showAsDropDown(view, -50, 0);

		}
	};

	/**
	 * Implement PopupItemAdapterEventCallback - choose menu option (sort by
	 * name/date)
	 * 
	 * @param view
	 *            the view
	 */
	@Override
	public void onSelectPopupItem(int position) {
		switch (position) {
		case 0:
			SORT_TYPE = SORT_NAME;
			break;

		case 1:
			SORT_TYPE = SORT_DATE;
			break;

		default:
			break;
		}
		// reset data in adapter listview
		current_travel_offset = 0;
		travels.clear();
		List<TravelModel> more_travels = getTraveListForSortType(SORT_TYPE,
				amount_travel, current_travel_offset);
		travels.addAll(more_travels);
		adapter_travels.notifyDataSetChanged();
		current_travel_offset += amount_travel;
		// move to listview's top
		lv_travels.setSelectionAfterHeaderView();
		// close list_popup
		if (list_popup != null && list_popup.isShowing()) {
			list_popup.dismiss();
		}
	}

	/**
	 * Implement TravelItemAdapterEventCallback - edit travel
	 * 
	 * @param view
	 *            the view
	 */
	@Override
	public void onEditTravel(View view) {
		int position = (Integer) view.getTag();
		selected_travel = travels.get(position);
		Intent intent = new Intent(A003_TravelList.this,
				A005_RegisterTravel.class);
		intent.putExtra(TravelSQLiteHelper.TRAVEL_ID, selected_travel.getId());
		startActivityForResult(intent, Constant.A003_CODE);
	}

	/**
	 * Implement TravelItemAdapterEventCallback - delete travel
	 * 
	 * @param view
	 *            the view
	 */
	@Override
	public void onDeleteTravel(View view) {
		int position = (Integer) view.getTag();
		selected_travel = travels.get(position);
		showDeleteTravelAlert(A003_TravelList.this,
				(TravelModel) selected_travel, A003_TravelList.this);
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see com.sl.diary.callback.AlertDialogCallBack#onAlertOKCallBack()
	 */
	@Override
	public void onAlertOKCallBack() {
		dbManager.deleteTravel(selected_travel.getId());
		updateList(Constant.TRAVEL_STATE_DEL, Constant.A003_CODE);
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see com.sl.diary.callback.AlertDialogCallBack#onAlertCancelCallBack()
	 */
	@Override
	public void onAlertCancelCallBack() {
		// TODO Auto-generated method stub

	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see
	 * com.sl.diary.adapter.TravelItemAdapter.TravelItemAdapterEventCallback
	 * #onShowTravelDetail(android.view.View)Implement
	 * 
	 * TravelItemAdapterEventCallback - show travel detail *
	 * 
	 * @param view - the view
	 */
	@Override
	public void onShowTravelDetail(View view) {

		int position = (Integer) view.getTag();
		selected_travel = travels.get(position);
		Intent intent = new Intent(A003_TravelList.this,
				A004_TravelDetail.class);
		intent.putExtra("travel_id", selected_travel.getId());
		startActivity(intent);

	}

	/**
	 * LoadDataTask - handle to load more travels
	 */
	private class LoadDataTask extends AsyncTask<Void, Void, Void> {

		@Override
		protected Void doInBackground(Void... params) {

			if (isCancelled()) {
				return null;
			}

			// Simulates a background task
			try {
				Thread.sleep(1000);
			} catch (InterruptedException e) {
			}

			List<TravelModel> more_travels = getTraveListForSortType(SORT_TYPE,
					amount_travel, current_travel_offset);
			travels.addAll(more_travels);
			current_travel_offset += amount_travel;

			return null;
		}

		@Override
		protected void onPostExecute(Void result) {
			// mListItems.add("Added after load more");

			// We need notify the adapter that the data have been changed
			adapter_travels.notifyDataSetChanged();

			// Call onLoadMoreComplete when the LoadMore task, has finished
			lv_travels.onLoadMoreComplete();

			super.onPostExecute(result);
		}

		@Override
		protected void onCancelled() {
			// Notify the loading more operation has finished
			lv_travels.onLoadMoreComplete();
		}
	}
}